using System;
using System.Linq;
using System.Web.Security;
using LeadTracker.DataAccess;
using LeadTracker.Models;

namespace LeadTracker.WebProviders
{
	public class LTExtendedMembershipProvider : WebMatrix.WebData.ExtendedMembershipProvider
	{



		UserRepository m_UserRepository;

		public override string ApplicationName { get; set; }

		public override bool EnablePasswordReset
		{
			get { return false; }
		}

		public override bool EnablePasswordRetrieval
		{
			get { return false; }
		}

		public override int MaxInvalidPasswordAttempts
		{
			get { throw new NotSupportedException(); }
		}

		public override int MinRequiredNonAlphanumericCharacters
		{
			get { return 0; }
		}

		public override int MinRequiredPasswordLength
		{
			get { return 1; }
		}

		public override int PasswordAttemptWindow
		{
			get { throw new NotSupportedException(); }
		}

		public override MembershipPasswordFormat PasswordFormat
		{
			get { return MembershipPasswordFormat.Hashed; }
		}

		public override string PasswordStrengthRegularExpression
		{
			get { throw new NotSupportedException(); }
		}

		public override bool RequiresQuestionAndAnswer
		{
			get { return false; }
		}

		public override bool RequiresUniqueEmail
		{
			get { return true; }
		}

		public override bool ChangePassword(string username, string oldPassword, string newPassword)
		{
			return m_UserRepository.ChangePassword(username, oldPassword, newPassword);
		}

		public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
		{
			throw new NotSupportedException();
		}

		public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
		{
			var newUser = new Editor();
			newUser.EmailAddress = email;
			newUser.FirstName = "Unknown";
			newUser.LastName = "Unknown";
			newUser.UserName = username;

			try
			{
				m_UserRepository.CreateUser(newUser, password);
				status = MembershipCreateStatus.Success;
				return CreateMembershipUser(newUser);
			}
			catch (CreateUserException ex)
			{
				switch (ex.ErrorCode)
				{
					case CreateUserError.DuplicateUserName:
						status = MembershipCreateStatus.DuplicateUserName;
						return null;
					case CreateUserError.DuplicateEmailAddress:
						status = MembershipCreateStatus.DuplicateEmail;
						return null;
					default:
						throw;
				}
			}
		}

		public override bool DeleteUser(string username, bool deleteAllRelatedData)
		{
			throw new NotSupportedException();
		}

		public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
		{
			var result = new MembershipUserCollection();
			var users = m_UserRepository.FindEditorsByEmailAddress(emailToMatch, pageIndex, pageSize, out totalRecords).Select(u => CreateMembershipUser(u));
			foreach (var user in users)
				result.Add(user);

			return result;
		}

		public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
		{
			var result = new MembershipUserCollection();
			var users = m_UserRepository.FindEditorsByUserName(usernameToMatch, pageIndex, pageSize, out totalRecords).Select(u => CreateMembershipUser(u));
			foreach (var user in users)
				result.Add(user);

			return result;
		}

		public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
		{
			var result = new MembershipUserCollection();
			var users = m_UserRepository.GetAllUsers(true, pageIndex, pageSize, out totalRecords).Select(u => CreateMembershipUser(u));
			foreach (var user in users)
				result.Add(user);

			return result;
		}

		public override int GetNumberOfUsersOnline()
		{
			return 0;
		}

		public override string GetPassword(string username, string answer)
		{
			throw new NotSupportedException();
		}

		public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
		{
			return CreateMembershipUser(m_UserRepository.LoadEditor((int)providerUserKey));
		}

		public override MembershipUser GetUser(string username, bool userIsOnline)
		{
			return CreateMembershipUser(m_UserRepository.LoadEditor(username));
		}

		public override string GetUserNameByEmail(string email)
		{
			var result = m_UserRepository.LoadEditorByEmailAddress(email);
			return result.UserName;
		}

		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			base.Initialize(name, config);

			var conString = System.Configuration.ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;

			m_UserRepository = new DataAccess.UserRepository(new Granite.Data.SqlServerConnection(conString));
		}

		public override string ResetPassword(string username, string answer)
		{
			throw new NotSupportedException();
		}

		public override bool UnlockUser(string userName)
		{
			throw new NotSupportedException();
		}

		public override void UpdateUser(MembershipUser user)
		{
			throw new NotSupportedException();
		}

		public override bool ValidateUser(string username, string password)
		{
			return m_UserRepository.ValidateUser(username, password);
		}

		MembershipUser CreateMembershipUser(Editor user)
		{
			return new MembershipUser(Name,
					   user.UserName,
					   user.EditorKey,
					   user.EmailAddress,
					   null,
					   null,
					   user.IsEnabled,
					   false,
					   default(DateTime),
					   default(DateTime),
					   default(DateTime),
					   default(DateTime),
					   default(DateTime));
		}


		public override bool ConfirmAccount(string accountConfirmationToken)
		{
			throw new NotImplementedException();
		}

		public override string CreateAccount(string userName, string password, bool requireConfirmationToken)
		{
			throw new NotImplementedException();
		}

		public override string CreateUserAndAccount(string userName, string password, bool requireConfirmation, System.Collections.Generic.IDictionary<string, object> values)
		{
			throw new NotImplementedException();
		}

		public override bool DeleteAccount(string userName)
		{
			throw new NotImplementedException();
		}

		public override string GeneratePasswordResetToken(string userName, int tokenExpirationInMinutesFromNow)
		{
			throw new NotImplementedException();
		}

		public override DateTime GetCreateDate(string userName)
		{
			throw new NotImplementedException();
		}

		public override DateTime GetLastPasswordFailureDate(string userName)
		{
			throw new NotImplementedException();
		}

		public override DateTime GetPasswordChangedDate(string userName)
		{
			throw new NotImplementedException();
		}

		public override int GetPasswordFailuresSinceLastSuccess(string userName)
		{
			throw new NotImplementedException();
		}

		public override int GetUserIdFromPasswordResetToken(string token)
		{
			throw new NotImplementedException();
		}

		public override bool IsConfirmed(string userName)
		{
			throw new NotImplementedException();
		}

		public override bool ResetPasswordWithToken(string token, string newPassword)
		{
			throw new NotImplementedException();
		}
	}
}
